package com.linktel.productionLine.EasyExcel.dailyPlanning;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.linktel.productionLine.EasyExcel.dailyAttendance.model.DailyAttendanceUnionKey;
import com.linktel.productionLine.EasyExcel.dailyPlanning.model.DailyPlanningUnionKey;
import com.linktel.productionLine.EasyExcel.dailyPlanning.model.WriteDailyPlanning;
import com.linktel.productionLine.EasyExcel.monthPlanning.model.MonthlyPlanningUnionKey;
import com.linktel.productionLine.EasyExcel.util.Methods;
import com.linktel.productionLine.common.BaseContext;
import com.linktel.productionLine.common.ErrorCode;
import com.linktel.productionLine.dao.BaseStepDao;
import com.linktel.productionLine.dao.DailyPlanningDao;
import com.linktel.productionLine.entity.dto.baseStep.BaseStepDTO;
import com.linktel.productionLine.entity.dto.dailyAttendance.AttendanceInfoDTO;
import com.linktel.productionLine.entity.dto.dailyPlanning.DailyPlanningDTO;
import com.linktel.productionLine.exception.BusinessException;
import com.linktel.productionLine.util.MethodUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 上传excel文件，批量保存日计划产能和排产，创建easyExcel读的监听器
 *
 */
@Slf4j
public class DailyPlanningListener extends AnalysisEventListener<WriteDailyPlanning> {

    private DailyPlanningDao dailyPlanningDao;
    private BaseStepDao baseStepDao;
    private Long currentUserId;
    private final List<WriteDailyPlanning> list = new ArrayList<>();
    private final List<DailyPlanningUnionKey> dailyPlanningUnionKeys = new ArrayList<>();
    private Integer loadingNumber = 0;
    private Integer repeatedNumber = 0;
    private Integer unusefulNumber = 0;
    private Integer editNumber = 0;
    private Integer increasedNumber = 0;

    public DailyPlanningListener(DailyPlanningDao dailyPlanningDao, Long currentUserId, BaseStepDao baseStepDao) {
        this.dailyPlanningDao = dailyPlanningDao;
        this.currentUserId = currentUserId;
        this.baseStepDao = baseStepDao;
    }

    @Override
    public void invoke(WriteDailyPlanning data, AnalysisContext context) {
        loadingNumber++;
        String productionLineCode = data.getProductionLineCode();
        String planningDateStr = data.getPlanningDate();
        String keyStepCode = data.getKeyStepCode();
        DailyPlanningUnionKey dailyPlanningUnionKey = new DailyPlanningUnionKey(productionLineCode, planningDateStr, keyStepCode);
        if (StringUtils.isAnyBlank(productionLineCode, planningDateStr, keyStepCode)) {
            log.info("{}, 传入的产线编码、关键工序、计划日期不能为空", data);
            unusefulNumber++;
            return ;
        }
        planningDateStr = Methods.getDateFromExcel(planningDateStr);

        data.setPlanningDate(planningDateStr);
        Calendar calendar = MethodUtils.getCalendarByDate(planningDateStr);
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH) + 1;
        List<String> baseCodeList = baseStepDao.listBaseStepByMonthlyPlanning(productionLineCode, year, month, currentUserId).stream().map(BaseStepDTO::getCode).collect(Collectors.toList());
        if (!baseCodeList.contains(keyStepCode)) {
            log.info("{}, 关键工序没有在月度规划中定义", data);
            unusefulNumber++;
            return ;
        }
        if (dailyPlanningUnionKeys.contains(dailyPlanningUnionKey)) {
            repeatedNumber++;
            return ;
        }
        dailyPlanningUnionKeys.add(dailyPlanningUnionKey);
        list.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        BaseContext.setCurrentLog("");
        saveData();
    }

    private void saveData() {
        log.info("------------  开始存储数据  ----------");
        if (list.size() > 0) {
            List<DailyPlanningDTO> dailyPlanningDTOList = dailyPlanningDao.listDailyPlanning(null, null, null, null);
            Map<DailyPlanningUnionKey, Long> map = new HashMap<>();
            dailyPlanningDTOList.forEach(item -> {
                map.put(new DailyPlanningUnionKey(item.getProductionLineCode(), item.getKeyStepCode(),item.getPlanningDate().toString()), item.getId());
            });
            list.forEach(item -> {
                DailyPlanningUnionKey dailyPlanningUnionKey = new DailyPlanningUnionKey(item.getProductionLineCode(), item.getKeyStepCode(), item.getPlanningDate());
                if (map.containsKey(dailyPlanningUnionKey)) {
                    editNumber++;
                    item.setId(map.get(dailyPlanningUnionKey));
                } else {
                    increasedNumber++;
                }
            });
            dailyPlanningDao.batchReplaceSave(list, currentUserId);
            BaseContext.setCurrentLog("加载到" + loadingNumber + "条数据，其中 "+ unusefulNumber +" 条不合法数据，" + repeatedNumber + "条重复数据；成功修改了" + editNumber + "条数据，新增了" + increasedNumber + "条数据。");
        } else {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "插入失败");
        }
    }

}
